package com.xiaowu.netmusic.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.xiaowu.netmusic.domain.dto.SongCreateDTO;
import com.xiaowu.netmusic.domain.dto.SongUpdateDTO;
import com.xiaowu.netmusic.domain.po.Song;
import com.xiaowu.netmusic.domain.vo.SongVO;
import com.xiaowu.netmusic.service.SongService;
import com.xiaowu.netmusic.utils.Result;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/songs")
@RequiredArgsConstructor
@Tag(name = "歌曲管理", description = "歌曲的增删查改 API")
public class SongController {

    private final SongService songService;

    @GetMapping
    @Operation(summary = "分页获取歌曲列表（可搜索）", description = "可传入关键词、页码和每页数量，返回歌曲分页列表")
    public Result<List<SongVO>> listAll(
            @RequestParam(defaultValue = "1") Long page,
            @RequestParam(defaultValue = "10") Long size,
            @RequestParam(required = false) String keyword
    ) {
        Page<Song> songPage = songService.lambdaQuery()
                .like(keyword != null && !keyword.isEmpty(), Song::getTitle, keyword)
                .or(keyword != null && !keyword.isEmpty())
                .like(Song::getArtist, keyword)
                .or(keyword != null && !keyword.isEmpty())
                .like(Song::getAlbum, keyword)
                .page(new Page<>(page, size));

        List<SongVO> songVOList = songPage.getRecords().stream().map(this::toVO).collect(Collectors.toList());
        return Result.success(songVOList);
    }


    @GetMapping("/{id}")
    @Operation(summary = "根据ID获取歌曲", description = "传入歌曲 ID，返回对应的歌曲详情")
    public Result<SongVO> getById(@PathVariable Long id) {
        Song song = songService.getById(id);
        if (song == null) return Result.error("歌曲不存在");
        return Result.success(toVO(song));
    }

    @PostMapping
    @Operation(summary = "新增歌曲", description = "传入新增歌曲信息")
    public Result<Void> add(@Valid @RequestBody SongCreateDTO dto) {
        Song song = new Song();
        BeanUtils.copyProperties(dto, song);
        songService.save(song);
        return Result.success();
    }

    @PutMapping
    @Operation(summary = "更新歌曲", description = "根据 ID 更新歌曲信息")
    public Result<Void> update(@Valid @RequestBody SongUpdateDTO dto) {
        Song song = songService.getById(dto.getId());
        if (song == null) return Result.error("歌曲不存在");

        BeanUtils.copyProperties(dto, song);
        songService.updateById(song);
        return Result.success();
    }

    @DeleteMapping("/{id}")
    @Operation(summary = "删除歌曲", description = "根据 ID 删除对应歌曲")
    public Result<Void> delete(@PathVariable Long id) {
        boolean removed = songService.removeById(id);
        if (!removed) return Result.error("删除失败，歌曲不存在");
        return Result.success();
    }

    private SongVO toVO(Song song) {
        SongVO vo = new SongVO();
        BeanUtils.copyProperties(song, vo);
        return vo;
    }

    @GetMapping("/{id}/play")
    @Operation(summary = "播放歌曲", description = "获取歌曲播放地址，并增加播放量")
    public Result<String> playSong(@PathVariable Long id) {
        Song song = songService.getById(id);
        if (song == null) return Result.error("歌曲不存在");

        // 播放量 +1
        song.setPlayCount(song.getPlayCount() + 1);
        songService.updateById(song);

        // 返回歌曲音频 URL（假设字段为 url）
        return Result.success(song.getAudioUrl());
    }

    @GetMapping("/top")
    @Operation(summary = "热门歌曲排行榜", description = "按播放量返回前 N 条热门歌曲")
    public Result<List<SongVO>> getTopSongs(@RequestParam(defaultValue = "10") Integer limit) {
        List<Song> topSongs = songService.lambdaQuery()
                .orderByDesc(Song::getPlayCount)
                .last("LIMIT " + limit)
                .list();

        List<SongVO> songVOList = topSongs.stream().map(this::toVO).collect(Collectors.toList());
        return Result.success(songVOList);
    }

    @GetMapping("/search")
    @Operation(summary = "搜索歌曲", description = "根据关键词搜索标题、歌手或专辑名")
    public Result<List<SongVO>> searchSongs(@RequestParam String keyword) {
        List<Song> songList = songService.lambdaQuery()
                .like(Song::getTitle, keyword)
                .or()
                .like(Song::getArtist, keyword)
                .or()
                .like(Song::getAlbum, keyword)
                .list();

        List<SongVO> songVOList = songList.stream().map(this::toVO).collect(Collectors.toList());
        return Result.success(songVOList);
    }
}
